package com.yxinsur.imc.business.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.yxinsur.imc.business.domain.*;
import com.yxinsur.imc.business.form.BrokerSearchForm;
import com.yxinsur.imc.business.mapper.*;
import com.yxinsur.imc.business.vo.BrokerVo;
import com.yxinsur.imc.business.vo.CommDetailsVo;
import com.yxinsur.imc.common.utils.DateUtils;
import com.yxinsur.imc.common.utils.SecurityUtils;
import com.yxinsur.imc.common.utils.StringUtils;
import com.yxinsur.imc.business.fact.*;
import org.drools.core.impl.InternalKnowledgeBase;
import org.drools.core.impl.KnowledgeBaseFactory;
import org.kie.api.KieBase;
import org.kie.api.io.ResourceType;
import org.kie.api.runtime.KieSession;
import org.kie.api.runtime.rule.FactHandle;
import org.kie.internal.builder.KnowledgeBuilder;
import org.kie.internal.builder.KnowledgeBuilderFactory;
import org.kie.internal.io.ResourceFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import java.math.BigDecimal;
import java.math.BigInteger;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

@Service
public class BasicService {

    @Autowired
    private ImcBrokerMapper imcBrokerMapper;
    @Autowired
    private ImcTeamMapper imcTeamMapper;
    @Autowired
    private ImcBrokerRelationMapper imcBrokerRelationMapper;
    @Autowired
    private ImcBrokerRoleMapper imcBrokerRoleMapper;
    @Autowired
    private ImcOrderRiskMapper imcOrderRiskMapper;
    @Autowired
    private ImcCommMapper imcCommMapper;
    @Autowired
    private ImcCommDetailsMapper imcCommDetailsMapper;
    @Autowired
    private ImcFundMapper imcFundMapper;
    @Autowired
    private ImcCommRiskMapper imcCommRiskMapper;
    @Autowired
    private ImcBrokerPersistencyRateMapper imcBrokerPersistencyRateMapper;
    @Autowired
    private KieBase kieBase;

    public List<BasicFACT> createFactList(Long commId, List<Long> brokerList, String settleMonth) {
        Long tenantId = SecurityUtils.getTenantId();
        ArrayList<BasicFACT> basicFACTS = new ArrayList<>();
        for (Long brokerId : brokerList) {
            BasicFACT basicFACT = new BasicFACT();
            //代理人信息 start
            //代理人基础信息 start
            BrokerInfo brokerInfo = new BrokerInfo();
            BrokerSearchForm brokerSearchForm = new BrokerSearchForm();
            brokerSearchForm.setId(brokerId);
            brokerSearchForm.setTenantId(tenantId);
            BrokerVo brokerVo = imcBrokerMapper.selectBasicImcBrokerBaseInfo(brokerSearchForm);
            BrokerInfoBase brokerInfoBase = new BrokerInfoBase();
            BeanUtils.copyProperties(brokerVo, brokerInfoBase);
            brokerInfoBase.setBrokerId(brokerVo.getId());
            //所在团队祖籍
            ImcTeam imcTeam = imcTeamMapper.selectImcTeamById(brokerInfoBase.getTeamId());
            String[] ids = imcTeam.getAncestors().split(",");
            List<BrokerInfoTeam> teamList = imcTeamMapper.selectTeamUpList(ids);
            brokerInfoBase.setTeamList(teamList);

            List<TeamBrokerInfo> teamBrokerIds = imcBrokerMapper.selectBrokerIdsByTeamId(brokerInfoBase.getTeamId(), tenantId);
            //团队直辖人员列表
            brokerInfoBase.setTeamBrokerIdList(teamBrokerIds);
            BigDecimal zhixiaPremOut = new BigDecimal(BigInteger.ZERO);
            for (TeamBrokerInfo teamBrokerId : teamBrokerIds) {
                Long zhixiaBrokerId = teamBrokerId.getBrokerId();
                ImcCommDetails zhixiaCommDetails = imcCommDetailsMapper.selectCommDetailsByBrokerId(zhixiaBrokerId, commId);
                if(zhixiaCommDetails==null){
                    continue;
                }
                zhixiaPremOut = zhixiaPremOut.add(zhixiaCommDetails.getStandPrem() == null ? BigDecimal.ZERO : zhixiaCommDetails.getStandPrem());
            }

            brokerInfo.setBrokerInfoBase(brokerInfoBase);
            //代理人基础信息end

            //代理人推荐信息 start
            BrokerInfoRelation brokerInfoRelation = new BrokerInfoRelation();
            //
            BrokerInfoRecom recomFirst = imcBrokerRelationMapper.getRecommend(brokerId);
            brokerInfoRelation.setRecomFirst(recomFirst);//1代推荐人
            BrokerInfoRecom recomSecond = imcBrokerRelationMapper.getRecommend(recomFirst.getRecomId());
            brokerInfoRelation.setRecomSecond(recomSecond);//2代推荐人
            List<BrokerInfoRecom> recomListFirst = imcBrokerRelationMapper.getRecommendGen(brokerId, tenantId, "1");
            brokerInfoRelation.setRecomListFirst(recomListFirst);//一代增员
            List<BrokerInfoRecom> recomListSecond = imcBrokerRelationMapper.getRecommendGen(brokerId, tenantId, "2");
            brokerInfoRelation.setRecomListSecond(recomListSecond);//二代增员
            brokerInfo.setBrokerInfoRelation(brokerInfoRelation);

            //代理人推荐信息 end

            //代理人职级信息 start
            List<BrokerInfoRole> brokerInfoRoleList = imcBrokerRoleMapper.selectBrokerInfoRoleByBrokerId(brokerId);//查询数据库
            brokerInfo.setBrokerInfoRoleList(brokerInfoRoleList);
            //代理人职级信息 end


            //代理人基本信息 end


            basicFACT.setBrokerInfo(brokerInfo);
            basicFACT.setOrderRiskTarget(new OrderRiskTarget());

            //指标信息

            //往期指标
            //查询基本法配置的往期口径
            ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
            ImcFund imcFund = imcFundMapper.selectImcFundById(imcComm.getFundId());
            String pastCaliber = imcFund.getPastCaliber();
            String pastCaliberDate = imcFund.getPastCaliberDate();
            String calDate = settleMonth + "-" + pastCaliberDate;//默认1号
            Date newDate = DateUtils.parseDate(calDate);
            int i = -1;
            String preCalendar1 = DateUtils.getPreCalendar(newDate, i);//举例  本月1号 7月26号
            Date past1end = DateUtils.parseDate(preCalendar1);
            String preCalendar2 = DateUtils.getPreCalendar(past1end, i);//举例 上月1号 6月26号
            Date past2end = DateUtils.parseDate(preCalendar2);
            String preCalendar3 = DateUtils.getPreCalendar(past2end, i);//举例 上上月1号 5月26号
            Date past3end = DateUtils.parseDate(preCalendar3);
            String preCalendar4 = DateUtils.getPreCalendar(past3end, i);//举例 4月26号
            Date past4end = DateUtils.parseDate(preCalendar4);
            String preCalendar5 = DateUtils.getPreCalendar(past4end, i);//举例 3月26号
            Date past5end = DateUtils.parseDate(preCalendar5);
            String preCalendar6 = DateUtils.getPreCalendar(past5end, i);//举例 2月26号
            Date past6end = DateUtils.parseDate(preCalendar6);

            //根据基本法配置的往期结算口径 配置相应的参数 代理人 租户  结算口径  日期  当月-1 为最小值  首年
            OrderRiskInfoFact orderRiskInfoPreFact1 = imcOrderRiskMapper.selectOrderRiskInfoFact(brokerId, pastCaliber, past2end, past1end);
            basicFACT.getOrderRiskTarget().setLastOrderRiskTargetFact1(orderRiskInfoPreFact1 == null ? new OrderRiskInfoFact() : orderRiskInfoPreFact1);

            OrderRiskInfoFact orderRiskInfoPreFact2 = imcOrderRiskMapper.selectOrderRiskInfoFact(brokerId, pastCaliber, past3end, past2end);
            basicFACT.getOrderRiskTarget().setLastOrderRiskTargetFact2(orderRiskInfoPreFact2 == null ? new OrderRiskInfoFact() : orderRiskInfoPreFact2);

            OrderRiskInfoFact orderRiskInfoPreFact3 = imcOrderRiskMapper.selectOrderRiskInfoFact(brokerId, pastCaliber, past4end, past3end);
            basicFACT.getOrderRiskTarget().setLastOrderRiskTargetFact3(orderRiskInfoPreFact3 == null ? new OrderRiskInfoFact() : orderRiskInfoPreFact3);

            OrderRiskInfoFact orderRiskInfoPreFact4 = imcOrderRiskMapper.selectOrderRiskInfoFact(brokerId, pastCaliber, past5end, past4end);
            basicFACT.getOrderRiskTarget().setLastOrderRiskTargetFact4(orderRiskInfoPreFact4 == null ? new OrderRiskInfoFact() : orderRiskInfoPreFact4);

            OrderRiskInfoFact orderRiskInfoPreFact5 = imcOrderRiskMapper.selectOrderRiskInfoFact(brokerId, pastCaliber, past6end, past5end);
            basicFACT.getOrderRiskTarget().setLastOrderRiskTargetFact5(orderRiskInfoPreFact5 == null ? new OrderRiskInfoFact() : orderRiskInfoPreFact5);


            //继续率

            //当月结算保单【新契约】
            ImcCommRisk imcCommRisk = new ImcCommRisk();
            imcCommRisk.setCommId(commId);
            imcCommRisk.setBrokerId(brokerId);
            imcCommRisk.setPolicyYear(1L);
            imcCommRisk.setIsDeleted("0");
            imcCommRisk.setTenantId(SecurityUtils.getTenantId());
            List<ImcCommRisk> imcCommRisks = imcCommRiskMapper.selectImcCommRiskList(imcCommRisk);
            basicFACT.setCommRiskInfoFirstList(imcCommRisks);

            //续期结算保单【续期】
            QueryWrapper<ImcCommRisk> wrapper = new QueryWrapper<>();
            wrapper.eq("comm_id", commId);
            wrapper.eq("broker_id", brokerId);
            wrapper.gt("policy_year", 1l);
            wrapper.eq("tenant_id", tenantId);
            wrapper.eq("is_deleted", "0");
            List<ImcCommRisk> imcCommRiskRenws = imcCommRiskMapper.selectList(wrapper);
            basicFACT.setCommRiskInfoRenwList(imcCommRiskRenws);

            //年度标保
            basicFACT.setYearStandPrem(getYearStandPrem(commId, brokerId, settleMonth));


            ImcCommDetails imcCommDetails = imcCommDetailsMapper.selectCommDetailsByBrokerId(brokerId, commId);
            basicFACT.setSettleMonth(settleMonth);
            basicFACT.setMonth(settleMonth.substring(4));
            basicFACT.setStandPrem(imcCommDetails.getStandPrem() == null ? BigDecimal.ZERO : imcCommDetails.getStandPrem());//当月fyp
            basicFACT.setSumCommission(imcCommDetails.getFirstComm() == null ? BigDecimal.ZERO : imcCommDetails.getFirstComm());//新契约佣金
            basicFACT.setRenwCommission(imcCommDetails.getRenewalComm() == null ? BigDecimal.ZERO : imcCommDetails.getRenewalComm());//续期佣金
            basicFACT.setZhixiaPrem(zhixiaPremOut.add(basicFACT.getStandPrem()));//直辖团队包含本人

            basicFACTS.add(basicFACT);
        }
        return basicFACTS;
    }

    /**
     * 查询代理人年度标保
     *
     * @param commId
     * @param brokerId
     * @param settleMonth
     * @return
     */
    private BigDecimal getYearStandPrem(Long commId, Long brokerId, String settleMonth) {
        ImcComm imcComm = imcCommMapper.selectImcCommById(commId);
        ImcFund imcFund = imcFundMapper.selectImcFundById(imcComm.getFundId());
        String pastCaliber = imcFund.getPastCaliber();
        String calDate = "";
        Long someDateWithSameMonth = 1L;
        if ("insure_date".equals(pastCaliber)) {
            calDate = imcFund.getInsureEndDate();
            someDateWithSameMonth = imcFund.getInsureWithSameMonth();
        } else if ("apply_date".equals(pastCaliber)) {
            calDate = imcFund.getApplyEndDate();
            someDateWithSameMonth = imcFund.getApplyWithSameMonth();
        } else if ("ack_date".equals(pastCaliber)) {
            calDate = imcFund.getAckEndDate();
            someDateWithSameMonth = imcFund.getAckWithSameMonth();
        }
        String calueDate = settleMonth + "-" + calDate;

        Date dateEnd = null;
        try {
            dateEnd = DateUtils.parseDate(calueDate, DateUtils.YYYY_MM_DD);
        } catch (ParseException e) {
            e.printStackTrace();
        }
        if (someDateWithSameMonth == 1) {//次月
            dateEnd = DateUtils.parseDate(DateUtils.getPreCalendar(dateEnd, 1));
        } else if (someDateWithSameMonth == -1) {//上月
            dateEnd = DateUtils.parseDate(DateUtils.getPreCalendar(dateEnd, -1));
        }
        Date dateStart = DateUtils.parseDate(DateUtils.getPreCalendar(dateEnd, -12));

        return imcOrderRiskMapper.selectYearStandPremByPastCaliberAndBrokerId(brokerId, pastCaliber, dateStart, dateEnd, SecurityUtils.getTenantId());
    }

    /**
     * 基本法计算
     *
     * @param fact
     */
    public void calculateCommission(Map<Long, BasicFACT> brokerFactMap, BasicFACT fact, String url) {
        KieSession kieSession = null;
        if (StringUtils.isEmpty(url)) {
            kieSession = kieBase.newKieSession();
        } else {
            //远程加载规则包
            KnowledgeBuilder kbuilder = KnowledgeBuilderFactory.newKnowledgeBuilder();
            kbuilder.add(ResourceFactory.newUrlResource(url), ResourceType.DRL);
            //创建知识库
            InternalKnowledgeBase knowledgeBase = KnowledgeBaseFactory.newKnowledgeBase();
            //将规则包添加到知识库中
            knowledgeBase.addPackages(kbuilder.getKnowledgePackages());
            //获得kieSession
            kieSession = knowledgeBase.newKieSession();
        }
        kieSession.setGlobal("factMap", new HashMap<String, BigDecimal>());
        kieSession.setGlobal("imcOrderRiskMapper", imcOrderRiskMapper);
        kieSession.setGlobal("brokerFactMap", brokerFactMap);
        kieSession.setGlobal("imcBrokerPersistencyRateMapper", imcBrokerPersistencyRateMapper);
        kieSession.insert(fact);

        int ruleFiredCount = kieSession.fireAllRules();
        System.out.println("触发了" + ruleFiredCount + "条规则");

        Collection<FactHandle> factHandles = kieSession.getFactHandles();
        for (FactHandle factHandle : factHandles) {
            BasicFACT basicFACT = (BasicFACT) kieSession.getObject(factHandle);
            BigDecimal profit1 = basicFACT.getProfit1();
            BigDecimal profit2 = basicFACT.getProfit2();
            BigDecimal profit3 = basicFACT.getProfit3();
            BigDecimal profit4 = basicFACT.getProfit4();
            BigDecimal profit5 = basicFACT.getProfit5();
            BigDecimal profit6 = basicFACT.getProfit6();
            BigDecimal profit7 = basicFACT.getProfit7();
            BigDecimal profit8 = basicFACT.getProfit8();
            BigDecimal profit9 = basicFACT.getProfit9();
            BigDecimal profit10 = basicFACT.getProfit10();
            BigDecimal profit11 = basicFACT.getProfit11();
            BigDecimal profit12 = basicFACT.getProfit12();
            BigDecimal profit13 = basicFACT.getProfit13();
            BigDecimal profit14 = basicFACT.getProfit14();
            BigDecimal profit15 = basicFACT.getProfit15();
            ImcCommDetails imcCommDetails = new ImcCommDetails();
            Long commDetailsId = basicFACT.getCommDetailsId();
            imcCommDetails.setId(commDetailsId);
            imcCommDetails.setBrokerId(basicFACT.getBrokerInfo().getBrokerInfoBase().getBrokerId());
            imcCommDetails.setProfit1(profit1);
            imcCommDetails.setProfit2(profit2);
            imcCommDetails.setProfit3(profit3);
            imcCommDetails.setProfit4(profit4);
            imcCommDetails.setProfit5(profit5);
            imcCommDetails.setProfit6(profit6);
            imcCommDetails.setProfit7(profit7);
            imcCommDetails.setProfit8(profit8);
            imcCommDetails.setProfit9(profit9);
            imcCommDetails.setProfit10(profit10);
            imcCommDetails.setProfit11(profit11);
            imcCommDetails.setProfit12(profit12);
            imcCommDetails.setProfit13(profit13);
            imcCommDetails.setProfit14(profit14);
            imcCommDetails.setProfit15(profit15);

            imcCommDetailsMapper.updateImcCommDetails(imcCommDetails);
        }
        kieSession.dispose();
    }


}
